package org.finesys.common.core.util;

import org.apache.commons.codec.binary.Hex;

import java.io.ByteArrayOutputStream;
import java.io.InputStream;
import java.net.HttpURLConnection;
import java.net.URI;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.util.*;
import java.util.function.Supplier;

public class Utils {


    public static <T> T getOrDefault(T value, T defaultValue) {
        return value != null ? value : defaultValue;
    }

    public static <T> T getOrDefault(T value, Supplier<T> defaultValueSupplier) {
        return value != null ? value : defaultValueSupplier.get();
    }

    public static boolean isNullOrBlank(String string) {
        return string == null || string.trim().isEmpty();
    }


    public static boolean isNotNullOrBlank(String string) {
        return !isNullOrBlank(string);
    }


    public static boolean areNotNullOrBlank(String... strings) {
        if (strings != null && strings.length != 0) {
            String[] var1 = strings;
            int var2 = strings.length;

            for (int var3 = 0; var3 < var2; ++var3) {
                String string = var1[var3];
                if (isNullOrBlank(string)) {
                    return false;
                }
            }

            return true;
        } else {
            return false;
        }
    }

    public static boolean isNullOrEmpty(Collection<?> collection) {
        return collection == null || collection.isEmpty();
    }

    public static boolean isNullOrEmpty(Iterable<?> iterable) {
        return iterable == null || !iterable.iterator().hasNext();
    }

    public static boolean isNullOrEmpty(Map<?, ?> map) {
        return map == null || map.isEmpty();
    }

    /**
     * @deprecated
     */

    public static boolean isCollectionEmpty(Collection<?> collection) {
        return isNullOrEmpty(collection);
    }

    public static String repeat(String string, int times) {
        StringBuilder sb = new StringBuilder();

        for (int i = 0; i < times; ++i) {
            sb.append(string);
        }

        return sb.toString();
    }

    public static String randomUUID() {
        return UUID.randomUUID().toString();
    }

    private static MessageDigest getSha256Instance() {
        try {
            return MessageDigest.getInstance("SHA-256");
        } catch (NoSuchAlgorithmException var1) {
            NoSuchAlgorithmException e = var1;
            throw new IllegalArgumentException(e);
        }
    }

    public static String generateUUIDFrom(String input) {
        byte[] hashBytes = getSha256Instance().digest(input.getBytes(StandardCharsets.UTF_8));
        String hexFormat = Hex.encodeHexString(hashBytes);
        return UUID.nameUUIDFromBytes(hexFormat.getBytes(StandardCharsets.UTF_8)).toString();
    }


    public static String ensureTrailingForwardSlash(String url) {
        return url.endsWith("/") ? url : url + "/";
    }

    public static String quoted(Object object) {
        return object == null ? "null" : "\"" + String.valueOf(object) + "\"";
    }

    public static String firstChars(String string, int numberOfChars) {
        if (string == null) {
            return null;
        } else {
            return string.length() > numberOfChars ? string.substring(0, numberOfChars) : string;
        }
    }

    public static byte[] readBytes(String url) {
        try {
            if (!url.startsWith("http://") && !url.startsWith("https://")) {
                return Files.readAllBytes(Paths.get(new URI(url)));
            } else {
                HttpURLConnection connection = (HttpURLConnection) (new URL(url)).openConnection();
                connection.setRequestMethod("GET");
                int responseCode = connection.getResponseCode();
                if (responseCode != 200) {
                    throw new RuntimeException("Error while reading: " + responseCode);
                } else {
                    InputStream inputStream = connection.getInputStream();
                    ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
                    byte[] buffer = new byte[1024];

                    int bytesRead;
                    while ((bytesRead = inputStream.read(buffer)) != -1) {
                        outputStream.write(buffer, 0, bytesRead);
                    }

                    return outputStream.toByteArray();
                }
            }
        } catch (Exception var7) {
            Exception e = var7;
            throw new RuntimeException(e);
        }
    }

    public static <T> List<T> copyIfNotNull(List<T> list) {
        return list == null ? null : Collections.unmodifiableList(list);
    }

    public static <K, V> Map<K, V> copyIfNotNull(Map<K, V> map) {
        return map == null ? null : Collections.unmodifiableMap(map);
    }
}
